package com.bc.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.bc.R;
import com.bc.db.dao.WarnDao;
import com.bc.db.entity.BtcNews;
import com.bc.db.entity.Warn;
import com.bc.service.BtcCategoryRequestListener;
import com.bc.service.deal.BtcCategory;
import com.bc.service.deal.ServiceCategory;
import com.bc.service.deal.ServiceFractory;
import com.bc.ui.setting.SettingActivity;
import com.bc.utils.CommonUtils;
import com.bc.utils.Constants;
import com.bc.utils.DBUtils;
import com.bc.utils.SettingPrefs;
import com.bc.utils.ThreadPoolManager;

public class BtcCacheOperator {
	private static final String TAG = "BtcCacheOperator";
	
	public static final int BACKGROUND_NOTIFI_ID = 1<<2;
	private List<BtcNews> btcNews = Collections.synchronizedList(new ArrayList<BtcNews>());
	
	public static BtcCacheOperator operator = null;
	
	private BtcCacheOperator() {
		
	}
	public static BtcCacheOperator getInstance() {
		if (operator == null) {
			operator = new BtcCacheOperator();
		}
		return operator;
	}
	
	
	public synchronized void initEnabledBtcNews(Context context) {
		btcNews = DBUtils.getEnabledBtcNews(context);
	}
	
	public void resetEnabledBtcNews() {
		btcNews.clear();
	}
	
	public List<BtcNews> getEnabledBtcNews() {
		return btcNews;
	}
	
	
	
	
	private List<BtcCategory> btcCategories = Collections.synchronizedList(new ArrayList<BtcCategory>());
	
	public void addBtcCategory(int position,BtcCategory bc) {
		if (btcCategories.size() <= position) {
			btcCategories.add(position, bc);
		}
	}
	
	public void setIndexBtcCategory(int position, BtcCategory bc) {
		btcCategories.set(position, bc);
	}
	
	public BtcCategory getBtcCategory(int position) {
		if (position > btcCategories.size()) {
			throw new RuntimeException("程序出错了");
		}
		return btcCategories.get(position);
	}
	
	public List<BtcCategory> getBtcCategories() {
		return btcCategories;
	}
	
	
	private HashMap<String, BtcCategory> lastBCHashMap = new HashMap<String, BtcCategory>();
	
	public void putBtcCategoryHashMap(String key, BtcCategory bc) {
		lastBCHashMap.put(key, bc);
	}
	
	public BtcCategory getBtcCategoryFromMap(String key) {
		return lastBCHashMap.get(key);
	}
	
//	private List<BtcCategory> lastBtcCategories = Collections.synchronizedList(new ArrayList<BtcCategory>());
	
//	public void setIndexLastBtcCategory(int position, BtcCategory bc) {
//		lastBtcCategories.set(position, bc);
//	}
//	
//	
//	public List<BtcCategory> getLastBtcCategories() {
//		return lastBtcCategories;
//	}
	
	public void resetBtcCategories() {
		btcCategories.clear();
	}
	
	private Map<String, ServiceCategory> serviceCatalogHashMap = new ConcurrentHashMap<String, ServiceCategory>();
	
	public void putServiceCatalog(String key, ServiceCategory sc) {
		serviceCatalogHashMap.put(key, sc);
	}
	
	public void resetServiceCatalogHashMap() {
		Iterator<Entry<String, ServiceCategory>> iterator = serviceCatalogHashMap.entrySet().iterator();
		while (iterator.hasNext()) {
			ServiceCategory sc = iterator.next().getValue();
			sc.cancelLoading();
		}
		serviceCatalogHashMap.clear();
	}
	
	public ServiceCategory getServiceCategory(String key) {
		return serviceCatalogHashMap.get(key);
	}
	
	private Map<String, Timer> timerHashMap = new ConcurrentHashMap<String, Timer>();
	public void addTimer(String key, Timer timer) {
		timerHashMap.put(key, timer);
	}
	
	public void clearTimerHashMap() {
		Iterator<Entry<String, Timer>> iterator = timerHashMap.entrySet().iterator();
		while (iterator.hasNext()) {
			Timer timer = iterator.next().getValue();
			if (timer != null) {
				timer.cancel();
				timer = null;
			}
		}
		timerHashMap.clear();
	}
	
	
	private Handler mHandler = new Handler();
	private int loadCount = 0;
	public synchronized void updateAllServiceData(final Context context) {
		for (int position = 0, size = BtcCacheOperator.getInstance().getEnabledBtcNews().size(); position < size; position ++) {
			final int index = position;
			BtcNews bn = BtcCacheOperator.getInstance().getEnabledBtcNews().get(position);
			final String key = bn.btcType;
			Log.d(TAG, "Key#" + key);
			final ServiceCategory serviceCategory = ServiceFractory.createService(context, key);
			if (serviceCategory == null) {
				Log.d(TAG, "serviceCategory is null....");
				return;
			}
			
			BtcCacheOperator.getInstance().addBtcCategory(index, null);
			
			ThreadPoolManager.getInstance().addTask(new Runnable() {
				
				@Override
				public void run() {
					serviceCategory.loadBtcData(new BtcCategoryRequestListener(index, key, context){
						
						@Override
						public void onComplete(final int errorCode) {
							loadCount ++;
							if (errorCode == 0) {
								BtcCategory bc = serviceCategory.getServieResponse();
								if (BtcCacheOperator.getInstance().getBtcCategories().size() > index) {
									BtcCategory lastBtcCategory = BtcCacheOperator.getInstance().getBtcCategory(index);
									if (lastBtcCategory != null) {
										Log.d(TAG, "set lastBtcCategory...");
										putBtcCategoryHashMap(key, lastBtcCategory);
									}
									BtcCacheOperator.getInstance().setIndexBtcCategory(index, bc);
								}
								checkNotification(context, index, bc);
								boolean sendNotifi = SettingPrefs.getInstance(context).getBooleanFromPrefs(SettingPrefs.EXIT_SERVICE_ON, false);
								if (sendNotifi) {
									sendBackgroundNotifi(context, index, bc);
								}
							}
						}
					});	
					
					
					/*Timer timer = new Timer();
					timer.schedule(new TimerTask() {
						
						@Override
						public void run() {
							serviceCategory.loadBtcData(new BtcCategoryRequestListener(index, key, context){
								
								@Override
								public void onComplete(final int errorCode) {
									if (errorCode == 0) {
										BtcCategory bc = serviceCategory.getServieResponse();
										if (BtcCacheOperator.getInstance().getBtcCategories().size() > index) {
											BtcCategory lastBtcCategory = BtcCacheOperator.getInstance().getBtcCategory(index);
											if (lastBtcCategory != null) {
												Log.d(TAG, "set lastBtcCategory...");
												putBtcCategoryHashMap(key, lastBtcCategory);
											}
											BtcCacheOperator.getInstance().setIndexBtcCategory(index, bc);
										}
										checkNotification(context, index, bc);
										boolean sendNotifi = SettingPrefs.getInstance(context).getBooleanFromPrefs(SettingPrefs.EXIT_SERVICE_ON, false);
										if (sendNotifi) {
											sendBackgroundNotifi(context, index, bc);
										}
									}
								}
							});	
						}
					}, 1000, 2 * 60 * 1000);*/
					
//					timerHashMap.put(key, timer);
				}
			});
		}
		
		mHandler.postDelayed(new Runnable() {
			
			@Override
			public void run() {
				if (loadCount >= BtcCacheOperator.getInstance().getEnabledBtcNews().size()) {
					Intent intent = new Intent(Constants.ACTION_HIDE_LOADING_REFRESH);
					LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
				}
			}
		}, 3000);
	}
	
	public void sendBackgroundNotifi(Context context, int position, BtcCategory bc) {
		if (bc == null) {
			return;
		}
		BtcNews bn = null;
		if (position < btcNews.size()) {
			bn = btcNews.get(position);
		} else {
			return;
		}
		HashMap<String, Object> mHashMap = bc.getBtcNews();
		CommonUtils.sendBackgroundNotifi(context, bn.btcName, CommonUtils.DisplayFormatString(bn.btcType, CommonUtils.ToString(mHashMap.get(Constants.LAST_SALE_PRICE)), context));
	}
	
	public void checkNotification(Context context, int position, BtcCategory bc) {
		if (bc == null) {
			return;
		}
		WarnDao dao = WarnDao.getInstance(context);
		String type = bc.getBtcType().trim();
		ArrayList<Warn> warnList = dao.queryItems(Constants.BTC_TYPE_COL+"=? and " + Constants.BTC_ENABLE_COL +"=1", new String[]{type});
		for (Warn warn : warnList) {
			double price = 0;
			String tip = "";
			if (warn.buy == 1) {
				Object priObject = bc.getBtcNews().get(Constants.BUY_ONE_PRICE);
				price = CommonUtils.ToDouble(priObject);
				tip = "买一价";
			} else {
				Object priObject = bc.getBtcNews().get(Constants.SELL_ONE_PRICE);
				price = CommonUtils.ToDouble(priObject);
				tip = "卖一价";
			}
			if (warn.over == 1) {
				if (price > warn.money) {
					tip += "超过";
					Bundle bundle = getNotficationBundle(bc, position);
					if ( bundle != null) {
						bundle.putInt("warn_position", warn.id);
						CommonUtils.sendNotification(context, context.getString(R.string.warn_tip) + ":" + tip + context.getString(R.string.formate_money, warn.money), bundle);
					}
					break;
				}
			} else {
				if (price < warn.money) {
					tip += "低于";
					Bundle bundle = getNotficationBundle(bc, position);
					if (bundle != null) {
						bundle.putInt("warn_position", warn.id);
						CommonUtils.sendNotification(context, context.getString(R.string.warn_tip) + ":" + tip + context.getString(R.string.formate_money, warn.money), bundle);
					}
					break;
				}
			}
		}
	}
	
	
	public Bundle getNotficationBundle(BtcCategory bc, int position) {
		HashMap<String, Object> hashMap = bc.getBtcNews();
		Bundle bundle = new Bundle();
		bundle.putString(Constants.LAST_SALE_PRICE, CommonUtils.ToString(hashMap.get(Constants.LAST_SALE_PRICE)));
		bundle.putString(Constants.BUY_ONE_PRICE, CommonUtils.ToString(hashMap.get(Constants.BUY_ONE_PRICE)));
		bundle.putString(Constants.SELL_ONE_PRICE, CommonUtils.ToString(hashMap.get(Constants.SELL_ONE_PRICE)));
		bundle.putString(Constants.SELL_HIGH_PRICE, CommonUtils.ToString(hashMap.get(Constants.SELL_HIGH_PRICE)));
		bundle.putString(Constants.SELL_LOW_PRICE, CommonUtils.ToString(hashMap.get(Constants.SELL_LOW_PRICE)));
		bundle.putString(Constants.SALE_VOLUME, CommonUtils.ToString(hashMap.get(Constants.SALE_VOLUME)));
		if (position < btcNews.size()) {
			bundle.putString(Constants.BTC_NAME_COL, btcNews.get(position).btcName);
		} else {
			return null;
		}
		
		bundle.putString(Constants.BTC_TYPE_COL, bc.getBtcType());
		return bundle;
	}
}
